package com.hongji.lms5xxcommunicator.grid.util;

import com.hongji.lms5xxcommunicator.entity.ScanPointEntity;
import com.hongji.lms5xxcommunicator.grid.core.GridSpec;

import java.util.*;

public final class Rasterizer {
    private Rasterizer(){}

    /** 原始点 → 单元格均值点（含范围过滤） */
    public static List<ScanPointEntity> toCellMeans(List<ScanPointEntity> raw, GridSpec spec) {
        if (raw == null || raw.isEmpty()) return Collections.emptyList();

        final int est = Math.max(16, raw.size() / 4);
        Map<Long, double[]> acc = new HashMap<>(est);

        for (ScanPointEntity p : raw) {
            if (p == null || p.getX()==null || p.getY()==null || p.getZ()==null) continue;
            double x = p.getX(), y = p.getY(), z = p.getZ();
            if (x < spec.x0 || x > spec.x1 || y < spec.y0 || y > spec.y1) continue;

            int c = (int)Math.floor((x - spec.x0) / spec.dx);
            int r = (int)Math.floor((y - spec.y0) / spec.dy);

            long key = (((long) r) << 32) ^ (c & 0xffffffffL);
            double[] a = acc.computeIfAbsent(key, k -> new double[]{0d, 0d});
            a[0] += z; // sum
            a[1] += 1; // cnt
        }

        List<ScanPointEntity> out = new ArrayList<>(acc.size());
        for (Map.Entry<Long, double[]> e : acc.entrySet()) {
            long key = e.getKey(); double[] a = e.getValue();
            int r = (int) (key >> 32);
            int c = (int) (key & 0xffffffffL);
            double meanZ = a[0] / a[1];

            ScanPointEntity s = new ScanPointEntity();
            s.setX(spec.x0 + (c + 0.5) * spec.dx);
            s.setY(spec.y0 + (r + 0.5) * spec.dy);
            s.setZ(meanZ);
            out.add(s);
        }
        return out;
    }
}
